/**
 * @file 	 mbrtu.h
 * @brief       
 * @author 	 wenbo
 * @version  1.0
 * @date 	 2023-03-21
 * 
 * @copyright Copyright (c) 2023  YGL
 * 
 */
#ifndef _MB_RTU_H
#define _MB_RTU_H

#include "../port/fmb_port.h"
#include "../include/mb.h"
#include "../include/mbconfig.h"
#include "../include/mbframe.h"
#include "../include/mbproto.h"
#include "../include/mbfunc.h"
#include "../include/mbport.h"
#include "../include/mbutils.h"

typedef struct mbSlave_ctx_st mbSlave_ctx;
typedef void(*inputReg_r_cb_t)(USHORT regAddr, USHORT regData);
typedef void(*holdReg_rw_cb_t)(USHORT regAddr, USHORT regData, BOOL isWrite);
typedef void(*coilsReg_rw_cb_t)(USHORT regAddr, BOOL isON, BOOL isWrite);
typedef void(*discreteReg_r_cb_t)(USHORT regAddr, BOOL isON);

// 协议栈平台适配层需要实现的接口,这里弱定义
extern eMBErrorCode eMBRTU_PortInit(UCHAR port, ULONG baudRate, eMBParity parity);
extern void eMBRTU_PortDeInit(UCHAR port);
extern eMBErrorCode eMBRTU_SendCB(UCHAR port, UCHAR* pData, ULONG size);
extern void* eMB_Malloc(ULONG size);
extern void eMB_Free(void *p);

/**
 * @brief       创建 mbSlave 实例(每个实例代表一个从机)
 * @param[in]	ucSlaveAddress      从机地址
 * @param[in]	ucPort              串口端口编号
 * @param[in]	ulBaudRate          波特率
 * @param[in]	eParity             校验方式
 * @return      mbSlave_ctx*        从机实例指针(结构体成员隐藏)
 */
mbSlave_ctx *mbSlave_creat(UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity);
/**
 * @brief       注册寄存器处理回调(仅在需要自定义处理回调时调用)
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	eMBRegInputCB       输入寄存器处理回调
 * @param[in]	eMBRegHoldingCB     保持寄存器处理回调
 * @param[in]	eMBRegCoilsCB       线圈寄存器处理回调
 * @param[in]	eMBRegDiscreteCB    离散寄存器处理回调
 */
void mbSlave_register_reg_callback(mbSlave_ctx* const ctx, 
									eMBRegInputCB_t eMBRegInputCB, 
									eMBRegHoldingCB_t eMBRegHoldingCB, 
									eMBRegCoilsCB_t eMBRegCoilsCB, 
									eMBRegDiscreteCB_t eMBRegDiscreteCB);
/**
 * @brief       注册指定地址输入寄存器读回调
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	regAddr             寄存器地址
 * @param[in]	cb                  寄存器处理回调
 * @return      BOOL                TRUE: 注册成功
 */
BOOL mbSlave_register_input_reg_callback(mbSlave_ctx* const ctx, USHORT regAddr, inputReg_r_cb_t cb);
/**
 * @brief       注册指定地址保持寄存器读写回调
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	regAddr             寄存器地址
 * @param[in]	cb                  寄存器处理回调
 * @return      BOOL                TRUE: 注册成功
 */
BOOL mbSlave_register_hold_reg_callback(mbSlave_ctx* const ctx, USHORT regAddr, holdReg_rw_cb_t cb);
/**
 * @brief       注册指定地址线圈寄存器读写回调
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	regAddr             寄存器地址
 * @param[in]	cb                  寄存器处理回调
 * @return      BOOL                TRUE: 注册成功
 */
BOOL mbSlave_register_coils_reg_callback(mbSlave_ctx* const ctx, USHORT regAddr, coilsReg_rw_cb_t cb);
/**
 * @brief       注册指定地址离散寄存器读写回调
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	regAddr             寄存器地址
 * @param[in]	cb                  寄存器处理回调
 * @return      BOOL                TRUE: 注册成功
 */
BOOL mbSlave_register_discrete_reg_callback(mbSlave_ctx* const ctx, USHORT regAddr, discreteReg_r_cb_t cb);
/**
 * @brief       映射输入寄存器地址
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	pRegBuf             输入寄存器内存地址
 * @param[in]	startAddr           输入寄存器起始地址(协议起始地址)
 * @param[in]	size                输入寄存器数量(单位 uint16_t)
 */
void mbSlave_mapping_input_reg(mbSlave_ctx* const ctx, USHORT *const pRegBuf, USHORT startAddr, USHORT size);
/**
 * @brief       映射保持寄存器地址
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	pRegBuf             保持寄存器内存地址
 * @param[in]	startAddr           保持寄存器起始地址(协议起始地址)
 * @param[in]	size                保持寄存器数量(单位 uint16_t)
 */
void mbSlave_mapping_hold_reg(mbSlave_ctx* const ctx, USHORT *const pRegBuf, USHORT startAddr, USHORT size);
/**
 * @brief       映射线圈寄存器地址
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	pRegBuf             线圈寄存器内存地址
 * @param[in]	startAddr           线圈寄存器起始地址(协议起始地址)
 * @param[in]	size                线圈寄存器数量(单位 uint16_t)
 */
void mbSlave_mapping_coils_reg(mbSlave_ctx* const ctx, UCHAR *const pRegBuf, USHORT startAddr, USHORT size);
/**
 * @brief       映射离散寄存器地址
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	pRegBuf             离散寄存器内存地址
 * @param[in]	startAddr           离散寄存器起始地址(协议起始地址)
 * @param[in]	size                离散寄存器数量(单位 uint16_t)
 */
void mbSlave_mapping_discrete_reg(mbSlave_ctx* const ctx, UCHAR *const pRegBuf, USHORT startAddr, USHORT size);
/**
 * @brief       mbSlave 解析处理函数(传入新接收到的数据进行解析回复)
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 * @param[in]	pData               接收到的数据指针(接口内会拷贝)
 * @param[in]	size                数据大小(byte)
 * @return      eMBErrorCode        MB_ENOERR: 无错误
 */
eMBErrorCode eMBRTU_Process(mbSlave_ctx* const  ctx, UCHAR* pData, USHORT size);
/**
 * @brief       销毁 mbSlave 实例(协议栈会调用底层串口DeInit)
 * @param[in]	ctx                 创建 mbSlave 时返回的句柄
 */
void mbSlave_distory(mbSlave_ctx* ctx);

#endif /* _MB_RTU_H */
